package com.eastfair.es;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.elasticsearch.model.PageResult;
import com.eastfair.es.dao.StudentDao;
import com.eastfair.es.entity.Student;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.indices.AnalyzeResponse;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.time.LocalDate;
import java.util.*;


/**
 * <p>
 * 前端控制器
 * 用户账户信息
 * </p>
 *
 * @author ligang
 * @date 2021-08-10
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/es")
@Api(value = "es", tags = "用户账户信息")
public class EsCollectionController {

    @Autowired
    StudentDao studentDao;


    @RequestMapping(value = "/add", method = RequestMethod.GET)
    @ResponseBody
    public R add(int num) {
        //添加
        Student student = new Student();
        student.setSAge(11);
        student.setId(UUID.randomUUID().toString());
        student.setSName("李刚");
        student.setSAddress("123123123123");
        studentDao.save(student);


        //批量添加
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            Date date = new Date();
            for (int j = 0; j < 10; j++) {

                student = new Student();
                student.setSAge(i);
                student.setId(UUID.randomUUID().toString());
                student.setSName("ligang"+getRandomChar(10));
                student.setSAddress(getRandomChar(50));

                LocalDate today = LocalDate.now();
                System.out.println("Today's Local date : " + today);

                student.setSCreateTime(new Date());
                List<String> sColorList = new ArrayList<>();
                sColorList.add(getRandomChar(10));
                sColorList.add(getRandomChar(10));
                sColorList.add(getRandomChar(10));
                sColorList.add(getRandomChar(10));
                student.setSColorList(sColorList);
                students.add(student);
            }
            studentDao.save(students);
            System.out.println(System.currentTimeMillis()-date.getTime());
        }

        return R.success(students);
    }



    @RequestMapping(value = "/test", method = RequestMethod.GET)
    @ResponseBody
    public R test() {
        //添加
        Student student = new Student();
        student.setSAge(11);
        student.setId(UUID.randomUUID().toString());
        student.setSName("李刚");
        student.setSAddress("123123123123");
        studentDao.save(student);


        //批量添加
        List<Student> students = new ArrayList<>();
//        for (int i = 0; i < 200; i++) {
//            for (int j = 0; j < 1000; j++) {
//                student = new Student();
//                student.setSAge(i);
//                student.setId(UUID.randomUUID().toString());
//                student.setSName("ligang"+getRandomChar(10));
//                student.setSAddress(getRandomChar(50));
//                student.setSCreateTime(new Date());
//                List<String> sColorList = new ArrayList<>();
//                sColorList.add(getRandomChar(10));
//                sColorList.add(getRandomChar(10));
//                sColorList.add(getRandomChar(10));
//                sColorList.add(getRandomChar(10));
//                student.setSColorList(sColorList);
//                students.add(student);
//            }
//            esService.save(students);
//            students = new ArrayList<>();
//        }

        //查询总条数
        NativeSearchQuery query = new NativeSearchQueryBuilder().build();
        long num = studentDao.queryCount(query, Student.class);
        System.out.println("总条数：" + num);

        //查询全部，默认查10条
//        List<Student> studentList = esService.matchAllQuery(Student.class);
//        log.info(JSON.toJSONString(studentList));

        //删除
//        String id = studentList.get(0).getId();
//        id="644798f4-cfe9-47b8-881f-ffaba70558ce";
//        Student student1 = esService.get(id, Student.class);
//        student1.setSName("ligang");
//        esService.update(id, student1, Student.class);
//        student1 =  esService.get(id,Student.class);
//        Boolean pan = esService.delete("9081bcc1-a3b9-4348-bcfb-43033f8a951c",Student.class);
//        student1 =  esService.get("9081bcc1-a3b9-4348-bcfb-43033f8a951c",Student.class);
//        log.info(JSON.toJSONString(student1));
        //4.批量删除
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("sName", "李刚").operator(Operator.AND).analyzer("ik_smart");
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
//        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);
//        esService.delete(nativeSearchQuery,Student.class);

//        num = esService.queryCount(query, Student.class);
//        System.out.println("总条数：" + num);

        PageResult<Student> selectFindPage = studentDao.selectFindPage(1, 20, "sName", "ligang", Student.class);
        log.info(JSON.toJSONString(selectFindPage));


        //分词
        try {
            List<AnalyzeResponse.AnalyzeToken> list = studentDao.selectBreakUpText("ik_smart", "北京天安门");
            log.info(JSON.toJSONString(list));
            List<AnalyzeResponse.AnalyzeToken> list2 = studentDao.selectBreakUpText("ik_max_word", "北京天安门");
            log.info(JSON.toJSONString(list2));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
//        List<Student> studentList1 = esService.termQuery("sName", Student.class, "ligang", "李刚2");
//        log.info(JSON.toJSONString(studentList1));
        //查询条件(词条查询：对应ES query里的match)
//        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("tAddress", "山东省济南市").operator(Operator.AND).analyzer("ik_smart");
//        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
//        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);
//        Boolean aBoolean = elasticsearchDeleteController.delete(nativeSearchQuery, Teacher.class);


//        List<AnalyzeResponse.AnalyzeToken> maxAnalyzeTokens = elasticsearchSelectController.selectBreakUpText("ik_max_word", "北京天安门");//细粒度分词
//        List<AnalyzeResponse.AnalyzeToken> smartAnalyzeTokens = elasticsearchSelectController.selectBreakUpText("ik_smart", "北京天安门");//粗粒度分词
//        System.err.println("maxAnalyzeTokens细粒度的size:" + maxAnalyzeTokens.size() + "\n" + "smartAnalyzeTokens粗粒度的size:" + smartAnalyzeTokens.size());


        return R.success();
    }


    @RequestMapping(value = "/test2", method = RequestMethod.GET)
    @ResponseBody
    public R test2(String id) {
        Student student1 = (Student) studentDao.get(id, Student.class);
        System.out.println(JSON.toJSONString(student1));
        student1.setSName("ligang");
        studentDao.update(id, student1, Student.class);

        return R.success();
    }

    @RequestMapping(value = "/findById", method = RequestMethod.GET)
    @ResponseBody
    public R findById(String id) {
        Student student1 = (Student) studentDao.get(id, Student.class);
        return R.success(student1);
    }

    @RequestMapping(value = "/findByName", method = RequestMethod.GET)
    @ResponseBody
    public R findByName(String name) {
        //精准查询
        List<Student> studentList1 = studentDao.termQuery("sName", Student.class, name);
        log.info(JSON.toJSONString(studentList1));

        PageResult<Student> selectFindPage = studentDao.selectFindPage(1, 20, "sName", "ligang", Student.class);
        log.info(JSON.toJSONString(selectFindPage));

        return R.success(studentList1);
    }

    /**
     * 分页查询
     *
     * @param key
     * @param value
     * @return
     */
    @RequestMapping(value = "/selectFindPage", method = RequestMethod.GET)
    @ResponseBody
    public R selectFindPage(Integer pageNum, Integer pageSize, String key, String value) {
        PageResult<Student> selectFindPage = studentDao.selectFindPage(pageNum, pageSize, key, value, Student.class);
        log.info(JSON.toJSONString(selectFindPage));
        return R.success(selectFindPage);
    }

    /**
     * 模糊查询
     *
     * @return
     */
    @RequestMapping(value = "/querylistPage", method = RequestMethod.GET)
    @ResponseBody
    public R regexpQuery(Integer pageNum, Integer pageSize,String name,String sAddress) {
        ContextUtil.setUserId(111111111111L);
        Student student = new Student();
        if(StringUtils.isNotBlank(name)){
            student.setSName(name);
        }
        if(StringUtils.isNotBlank(sAddress)){
            student.setSAddress(sAddress);
        }
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(student));
        PageResult<Student> studentPageResult = studentDao.querylistPage(pageNum, pageSize, jsonObject,Student.class,null);
        log.info(JSON.toJSONString(studentPageResult));
        return R.success(studentPageResult);
    }


    /**
     * 正则表达式
     *
     * @param key
     * @param value
     * @return
     */
    @RequestMapping(value = "/wildcardQuery", method = RequestMethod.GET)
    @ResponseBody
    public R wildcardQuery( String key, String value) {
        List<Student> studentList = studentDao.wildcardQuery(key, value,Student.class);
        log.info(JSON.toJSONString(studentList));
        return R.success(studentList);
    }
    /**
     * 高亮查询
     *
     * @param key
     * @param value
     * @return
     */
    @RequestMapping(value = "/highlightQuery", method = RequestMethod.GET)
    @ResponseBody
    public R highlightQuery(Integer pageNum, Integer pageSize, String key, String value) {
        PageResult<Student> studentPageResult = studentDao.highlightBuilder(pageNum, pageSize,
                key, "<font color='red'>", "</font>", value, Student.class);
        log.info(JSON.toJSONString(studentPageResult));
        return R.success(studentPageResult);
    }



    /**
     * anc查询
     *
     * @return
     */
    @RequestMapping(value = "/boolQueryBuilderByMust", method = RequestMethod.GET)
    @ResponseBody
    public R boolQueryBuilderByMust( String name, String address) {
        Map<String, String[]> fields = new HashMap<>();
        fields.put("sName",new String[]{name});
        fields.put("sAddress",new String[]{address});
        List<Student> studentPageResult = studentDao.boolQueryBuilderByMust(fields, Student.class);
        log.info(JSON.toJSONString(studentPageResult));
        return R.success(studentPageResult);
    }

    private String getRandomChar(int num) {
        StringBuffer s = new StringBuffer();
        for (int i = 0; i < num; i++) {
            s.append(getRandomChar());
        }
        return s.toString();
    }


    private char getRandomChar() {
        String str = "";
        int hightPos; //
        int lowPos;

        Random random = new Random();

        hightPos = (176 + Math.abs(random.nextInt(39)));
        lowPos = (161 + Math.abs(random.nextInt(93)));

        byte[] b = new byte[2];
        b[0] = (Integer.valueOf(hightPos)).byteValue();
        b[1] = (Integer.valueOf(lowPos)).byteValue();

        try {
            str = new String(b, "GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.out.println("错误");
        }

        return str.charAt(0);
    }

}
